#pragma once
#include <string>
#include <memory>
#include <rclcpp/rclcpp.hpp>
#include <behaviortree_cpp/behavior_tree.h>
#include <behaviortree_cpp/bt_factory.h>

#include "fishbot_behavior_tree/behavior_context.hpp"

typedef BT::TreeNode BehaviorTreeT;

namespace fishbot::behavior_tree
{
    class SharedResourcesNodeLoaderBase
    {
    public:
        virtual void registerBehaviors(BT::BehaviorTreeFactory &factory, const std::shared_ptr<BehaviorContext> &shared_resources) = 0;

    protected:
        SharedResourcesNodeLoaderBase() {}
    };

    template <typename BehaviorTreeT>
    void registerBehaviorNotSharedResources(BT::BehaviorTreeFactory &factory,
                          const std::string &name,
                          const std::shared_ptr<BehaviorContext> &shared_resources)
    {
        factory.registerNodeType<BehaviorTreeT>(name);
        RCLCPP_INFO_STREAM(shared_resources->node_->get_logger(), "Register: " << name);
    }

    template <typename BehaviorTreeT>
    void registerBehavior(BT::BehaviorTreeFactory &factory,
                          const std::string &name,
                          const std::shared_ptr<BehaviorContext> &shared_resources)
    {
        factory.registerNodeType<BehaviorTreeT>(name, shared_resources);
        RCLCPP_INFO_STREAM(shared_resources->node_->get_logger(), "Register: " << name);
    }
}